<template>
  <div class="view_wrap" style="padding: 2px">
    <div ref="wrap" style="width: 100%; height: 100%">
      <canvas v-show="true" :id="canvasName" width="100%" height="100%" />
    </div>
    <div class="img_loading" v-if="isLoading">
      <div>
        <i class="el-icon-loading"></i>
      </div>
    </div>
    <div class="line" v-if="markPicList.length > 1"></div>
    <div class="timelines" v-if="markPicList.length > 1">
      <div
        class="item"
        v-for="(item, index) in markPicList"
        :key="index"
        @click="changePhoto(item)"
      >
        <div
          class="slot"
          :class="[
            { hasmark: item.tags.length > 0 },
            { active: markPicObj.photo_id == item.photo_id },
          ]"
        ></div>
        <div
          class="txt"
          :class="{ active: markPicObj.photo_id == item.photo_id }"
        >
          <span>{{ timeAgo(item.photo_time) }}</span>
          <span>{{ item.photo_time | timeFilter }}</span>
        </div>
      </div>
    </div>
    <div class="zoom_wrap" v-if="showZoomTool">
      <button class="btn_zoom" @click="zoomCanvas(0.2)">+</button>
      <button class="btn_zoom" @click="zoomCanvas(-0.2)">-</button>
    </div>
  </div>
</template>

<script>
import { fabric } from "fabric";
import { problemHistory, markProjection, getMarkPlat } from "@/api/censuisdata";
import { timeago } from "@/utils/formatTime";
import { addUrlToken } from "@/utils/allTool";

export default {
  name: "IssueViewer",
  filters: {
    timeFilter(text) {
      var a = text.split(" ");
      a = a[0];
      return a;
    },
  },

  props: {
    url2: {
      type: String,
      default: () => "",
    },
    points2: {
      type: Array,
      default: () => [],
    },
    markPicObj2: {
      type: Object,
      default: () => {},
    },
    selectItemMarkId: {
      type: String,
      default: () => "",
    },
    showZoomTool: {
      type: Boolean,
      default: () => true,
    },
    canvasName: {
      type: String,
      default: () => "c",
    },
    selectItem: {
      type: Object,
      default: () => null,
    },
  },
  data() {
    return {
      canvas: "",
      url: this.url2,
      points: this.points2,
      markPicObj: this.markPicObj2,
      // markImgId:this.markPicObj2.photo_id,
      markImgId: this.selectItemMarkId,
      markPicList: [],
      isShowCanvas: true,
      isLoading: false,
      otherMarkerList: [],
    };
  },
  watch: {
    url2: {
      handler(val) {
        console.log("url2ssssss", val);
        if (val) {
          this.url = val;
        }
        this.canvas && this.drawImgAndMarks(this.canvas);
      },
    },
  },
  mounted() {
    this.getTimeAxis(this.markPicObj2);
    this.requestOtherIssueMarker(this.markPicObj2);
    this.initCanvasStyle();
    this.initCanvasEvent(this.canvas);
    this.drawImgAndMarks(this.canvas);
  },
  methods: {
    requestOtherIssueMarker(data) {
      if (!data?.photo_id) return false;
      getMarkPlat({
        photo_id: data.photo_id,
      }).then((res) => {
        if (res?.msg === "ok") {
          this.otherMarkerList = res.data?.mark?.filter(
            (item) => item.mark_id !== this.selectItem?.markId
          );
        }
      });
    },
    getTimeAxis(markObj) {
      if (markObj) {
        problemHistory({
          markPositionLongitude: markObj.markPositionLongitude,
          markPositionLatitude: markObj.markPositionLatitude,
          photo_time: markObj.photo_time,
          sceneName: markObj.sceneName,
          photo_id: markObj.photo_id,
        }).then((res) => {
          if (res.data) {
            this.markPicList = res.data;
          }
        });
      }
    },
    async changePhoto(item) {
      var _this = this;
      _this.markPicObj.photo_id = item.photo_id;
      _this.markPicObj.photo_time = item["photo_time"];
      _this.url = item.photo_url;
      _this.isLoading = true;
      this.requestOtherIssueMarker(item.photo_id);
      if (item["tags"].length > 0) {
        _this.points = [item.tags[0].points];
        _this.drawImgAndMarks(_this.canvas);
      } else {
        markProjection({
          position: [
            _this.markPicObj["markPositionLongitude"],
            _this.markPicObj["markPositionLatitude"],
          ],
          photo_info_code: item["photo_id"],
        }).then((res) => {
          var point = res.data;
          if (point[0] != -1) {
            var obj = {
              points: [
                [point[0] - 300, point[1] - 300],
                [point[0] + 300, point[1] + 300],
              ],
              tag_name: "",
            };
            _this.points = [obj.points];
          } else {
            _this.points = [];
          }
          _this.$bus.emit("etlines", {
            item: item,
            points: _this.points,
          });
          _this.drawImgAndMarks(_this.canvas);
        });
      }
    },
    zoomCanvas(val) {
      console.log("this.my_canvas", this.canvas);
      var zoom = val + this.canvas.getZoom();
      zoom = Math.max(1, zoom); //最小为原来的1/10
      zoom = Math.min(10, zoom); //最大是原来的3倍
      var zoomPoint = new fabric.Point(
        this.canvas.width / 2,
        this.canvas.height / 2
      );

      this.canvas.zoomToPoint(zoomPoint, zoom);
      //rect边框自适应缩放
      this.canvas.forEachObject(function (obj) {
        if (obj.strokeWidth) {
          obj.set({
            strokeWidth: 2 / zoom,
          });
        } else if (obj._objects[0].strokeWidth) {
          obj._objects[0].set({
            strokeWidth: 2 / zoom,
          });
        }
      });
      this.canvas.renderAll();
    },
    timeAgo(val) {
      return timeago(val);
    },
    initCanvasStyle() {
      const canvasWidth = this.$refs.wrap.clientWidth;
      const canvasHeight = this.$refs.wrap.clientHeight;
      this.canvas = new fabric.Canvas(this.canvasName, {
        width: canvasWidth,
        height: canvasHeight,
        selection: true,
        crossOrigin: "anonymous",
      });
    },
    initCanvasEvent(canvas) {
      canvas.on("mouse:wheel", function (opt) {
        var delta = opt.e.deltaY; // 在向下滚动时返回正值，向上滚动时返回负值，否则为0。
        var zoom = canvas.getZoom();
        zoom *= 0.999 ** delta;
        if (zoom > 20) zoom = 20;
        if (zoom < 0.01) zoom = 0.01;
        canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom);
        // rect边框自适应缩放
        canvas.forEachObject(function (obj) {
          if (obj.strokeWidth) {
            obj.set({
              strokeWidth: 2 / zoom,
            });
          } else if (obj._objects[0].strokeWidth) {
            obj._objects[0].set({
              strokeWidth: 2 / zoom,
            });
          }
        });
        canvas.renderAll();
        opt.e.preventDefault();
        opt.e.stopPropagation();
      });
      canvas.on("mouse:down", function (opt) {
        const evt = opt.e;
        this.isDragging = true;
        this.selection = false;
        this.lastPosX = evt.clientX;
        this.lastPosY = evt.clientY;
      });
      canvas.on("mouse:move", function (opt) {
        if (this.isDragging) {
          var e = opt.e;
          var vpt = this.viewportTransform;
          vpt[4] += e.clientX - this.lastPosX;
          vpt[5] += e.clientY - this.lastPosY;
          this.requestRenderAll();
          this.lastPosX = e.clientX;
          this.lastPosY = e.clientY;
        }
      });
      canvas.on("mouse:up", function (opt) {
        // on mouse up we want to recalculate new interaction
        // for all objects, so we call setViewportTransform
        this.setViewportTransform(this.viewportTransform);
        this.isDragging = false;
        this.selection = true;
      });
    },
    drawImgAndMarks(canvas, drawMulti) {
      var _this = this;
      let scaleWidth, scaleHeight;
      // 清空画布
      _this.canvas.clear();
      fabric.Image.fromURL(addUrlToken(_this.url), (img) => {
        scaleWidth = canvas.width / img.width;
        scaleHeight = canvas.height / img.height;
        // const scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight
        canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
          scaleX: scaleWidth, // 计算出图片要拉伸的宽度
          scaleY: scaleHeight, // 计算出图片要拉伸的高度
        });
        //
        _this.drawMarks(canvas, _this.points, scaleWidth, scaleHeight);
        // 绘制其他标注框
        if (drawMulti && _this.otherMarkerList?.length > 0) {
          _this.otherMarkerList.forEach((mark) => {
            mark.points &&
              this.drawMarks(
                canvas,
                [mark.points],
                scaleWidth,
                scaleHeight,
                "rgba(240, 240, 240, 0.9)"
              );
          });
        }
      });
    },
    drawMarks(canvas, marks, scaleWidth, scaleHeight, color) {
      var _this = this;
      for (let i = 0; i < marks.length; i++) {
        const points = marks[i];
        const originTop = points[0][1];
        const originLeft = points[0][0];
        const originWidth = points[1][0] - points[0][0];
        const originHeight = points[1][1] - points[0][1];
        const rect = new fabric.Rect({
          top: originTop * scaleHeight, // 距离容器顶部 30px
          left: originLeft * scaleWidth, // 距离容器左侧 30px
          width: originWidth * scaleWidth, // 宽 100px
          height: originHeight * scaleHeight, // 高 60px
          fill: null, // 填充 红色
          stroke: color || "red", // 边框原色
          strokeWidth: 2, // 边框大小

          selectable: false,
          hoverCursor: "default",
        });
        console.log(_this.markImgId);
        if (_this.markImgId != _this.markPicObj.photo_id) {
          rect.strokeDashArray = [6, 6];
        }
        canvas.add(rect);
      }
      _this.isLoading = false;
      _this.canvas.setViewportTransform([1, 0, 0, 1, 0, 0]);
    },
  },
  created() {
    var _this = this;
    _this.$bus.on("changeIssueImgScale", (bool) => {
      const canvasWidth = this.$refs.wrap.clientWidth;
      const canvasHeight = this.$refs.wrap.clientHeight;
      console.log(canvasWidth);
      setTimeout(function () {
        _this.canvas.setViewportTransform([1, 0, 0, 1, 0, 0]);
      }, 50);
    });

    _this.$bus.on("showAllIssue", (data) => {
      this.drawImgAndMarks(this.canvas, data);
    });
  },
  beforeDestroy() {
    this.$bus.off("changeIssueImgScale");
    this.$bus.off("showAllIssue");
  },
};
</script>

<style lang="scss" scoped>
.view_wrap {
  //height: vh(800);
  //width: vh(1200);
  //background: grey;
  //position: fixed;
  //right: 360px;
  //bottom: vh(18);
  //background: rgba(255, 104, 34, 0.1);
  //background: no-repeat center url('~@/assets/border/z2.png');
  //background-size: 100% 100%;
  //padding: vh(27) vh(23) vh(26) vh(22);
  background: rgba(5, 29, 40, 0.8);

  .img {
    width: 100%;
    height: 100%;
  }

  .line {
    position: absolute;
    right: 115px;
    top: 0;
    width: 2px;
    height: 100%;
    z-index: 1;
    background-color: rgba(243, 243, 243, 0.7);
  }

  .timelines {
    position: absolute;
    width: 120px;
    right: 10px;
    top: 2px;
    padding: 0 10px;
    height: calc(100% - 4px);
    overflow-y: auto;
    z-index: 2;

    // border-left: 2px solid rgba(243,243,243,0.7);
    &:hover {
      background-color: rgba(0, 0, 0, 0.3);
    }

    .item {
      color: white;
      display: flex;
      position: relative;
      padding-top: 20px;
      padding-bottom: 5px;
      cursor: pointer;
      font-size: 15px;

      &:hover .slot {
        background-color: rgba(0, 255, 255, 0.9);
      }

      .slot {
        margin-left: -3px;
        width: 14px;
        height: 14px;
        border-radius: 7px;
        background-color: white;
        margin-top: 5px;
        box-shadow: 0 0 4px rgba(0, 0, 0, 0.8);

        &.active {
          background-color: #ff0000 !important;
          transform: scale(1.3);
        }

        &.hasmark {
          background-color: #ffaa00;
        }
      }

      .txt {
        display: flex;
        flex-direction: column;
        margin-left: 8px;
        text-shadow: 0 0 4px rgba(0, 0, 0, 0.8);

        //font-size: vw(18);
        span:nth-child(2) {
          font-size: 14px;
          font-weight: 600;
          color: #7ed0ff;
        }

        &.active {
          font-size: 18px;
          margin-left: 10px;
        }
      }
    }
  }

  .img_loading {
    position: absolute;
    height: 100%;
    width: 100%;
    background: rgba(0, 0, 0, 0.5);
    top: 0;
    left: 0;
    z-index: -1;

    > div {
      color: #fff;
      font-size: 36px;
      width: 50px;
      margin: 0 auto;
      padding-top: 30%;
    }
  }

  .zoom_wrap {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 10px;
    left: 10px;
    font-size: 15px;
  }
}
</style>
